using System.Collections.Generic;
using System.Linq;
using System.Net;
using Engine;
using Engine.Graphics;
using Game;

namespace RuthlessConquest {
    public class GameListScreen : Screen {
        public bool UpgradeDialogShown;
        public Dictionary<GameDescription, Texture2D> GameImageTexturesCache = new();
        public ListPanelWidget GamesList;
        public ButtonWidget JoinButton;
        public ButtonWidget SpectateButton;
        public ButtonWidget CreateButton;
        public ButtonWidget BackButton;
        public const string fName = "RCGameListScreen";

        public GameListScreen() {
            IsDrawRequired = true;
            Widget[] obj = [new BackgroundWidget(), new BoidsWidget(), new InterlaceWidget(), null];
            StackPanelWidget panel1 = new() {
                Direction = LayoutDirection.Vertical,
                Margin = new Vector2(20f, 0f),
                Children = {
                    new CanvasWidget { Size = new Vector2(0f, 10f) },
                    new CanvasWidget {
                        Size = new Vector2(float.PositiveInfinity, -1f),
                        Children = {
                            new LabelWidget {
                                Text = LanguageControl.Get(fName, "1"),
                                FontScale = 0.75f,
                                Color = Colors.Fore,
                                HorizontalAlignment = WidgetAlignment.Center
                            },
                            new BusyBarWidget {
                                HorizontalAlignment = WidgetAlignment.Far, VerticalAlignment = WidgetAlignment.Center, LitBarColor = Colors.High
                            }
                        }
                    },
                    new CanvasWidget { Size = new Vector2(0f, 10f) }
                }
            };
            CanvasWidget obj3 = new() {
                Size = new Vector2(float.PositiveInfinity, float.PositiveInfinity), Children = { new RectangleWidget(), new InterlaceWidget() }
            };
            GamesList = new ListPanelWidget { Direction = LayoutDirection.Vertical, ItemSize = 82f, Margin = new Vector2(2f, 2f) };
            obj3.Children.Add(GamesList);
            panel1.Children.Add(obj3);
            panel1.Children.Add(new CanvasWidget { Size = new Vector2(0f, 20f) });
            StackPanelWidget panel2 = new() { Direction = LayoutDirection.Horizontal, HorizontalAlignment = WidgetAlignment.Center };
            JoinButton = new BevelledButtonWidget {
                Text = LanguageControl.Get(fName, "2"), Size = new Vector2(240f, 60f), Margin = new Vector2(20f, 0f)
            };
            panel2.Children.Add(JoinButton);
            SpectateButton = new BevelledButtonWidget {
                Text = LanguageControl.Get(fName, "3"), Size = new Vector2(200f, 60f), Margin = new Vector2(20f, 0f)
            };
            panel2.Children.Add(SpectateButton);
            CreateButton = new BevelledButtonWidget {
                Text = LanguageControl.Get(fName, "4"), Size = new Vector2(280f, 60f), Margin = new Vector2(20f, 0f)
            };
            panel2.Children.Add(CreateButton);
            BackButton = new BevelledButtonWidget {
                Text = LanguageControl.Back, Size = new Vector2(200f, 60f), Margin = new Vector2(20f, 0f), Sound = "RCSounds/Click2"
            };
            panel2.Children.Add(BackButton);
            panel1.Children.Add(panel2);
            panel1.Children.Add(new CanvasWidget { Size = new Vector2(0f, 10f) });
            obj[3] = panel1;
            Children.Add(obj);
            GamesList.ScrollPosition = 0f;
            GamesList.ItemWidgetFactory = delegate(object item) {
                GameDescription gameDescription = (GameDescription)item;
                string text;
                string text2;
                string text3;
                if (gameDescription.ServerDescription.IsLocal) {
                    text = LanguageControl.Get(fName, "5");
                    text2 = string.Format(LanguageControl.Get(fName, "6"), gameDescription.CreationParameters.CreatingPlayerName);
                    text3 = string.Format(LanguageControl.Get(fName, "7"), ShortenAddress(gameDescription.ServerDescription.Address.Address));
                }
                else {
                    text = LanguageControl.Get(fName, "8");
                    text2 = string.Format(LanguageControl.Get(fName, "6"), gameDescription.CreationParameters.CreatingPlayerName);
                    text3 = string.Format(LanguageControl.Get(fName, "7"), gameDescription.ServerDescription.Name);
                }
                string text4 = string.Format(
                    LanguageControl.Get(fName, "9"),
                    gameDescription.CreationParameters.PlanetsCount,
                    gameDescription.CreationParameters.SpecialPlanetsCount,
                    Ship.GetShipRangeName((ShipRange)gameDescription.CreationParameters.ShipRange).ToLower(),
                    Player.GetPlayerTypeName(gameDescription.CreationParameters.AILevel).ToLower(),
                    gameDescription.CreationParameters.NeutralsPopulationFactor,
                    7500 / gameDescription.CreationParameters.SpecialEventsPeriod
                );
                string text5 = string.Format(
                    LanguageControl.Get(fName, "10"),
                    gameDescription.HumanPlayersCount,
                    gameDescription.CreationParameters.MaxHumanPlayersCount,
                    gameDescription.SpectatorsCount,
                    !(gameDescription.ServerDescription.Ping > 0f) || !(gameDescription.ServerDescription.Ping < 3f)
                        ? LanguageControl.Get(fName, "11")
                        : string.Format(LanguageControl.Get(fName, "12"), (gameDescription.ServerDescription.Ping * 1000f).ToString("0"))
                );
                if (gameDescription.TicksSinceStart > 0) {
                    int num = (int)(gameDescription.TicksSinceStart * 0.5f);
                    text5 += string.Format(LanguageControl.Get(fName, "13"), $"{num / 60:00}:{num % 60:00}");
                }
                if (!GameImageTexturesCache.TryGetValue(gameDescription, out Texture2D value)) {
                    value = gameDescription.GameImage != null
                        ? gameDescription.GameImage.Draw((X: 192, Y: 108), gameDescription.TicksSinceStart < 0)
                        : null;
                    GameImageTexturesCache.Add(gameDescription, value);
                }
                return new StackPanelWidget {
                    HorizontalAlignment = WidgetAlignment.Near,
                    VerticalAlignment = WidgetAlignment.Center,
                    Children = {
                        new CanvasWidget { Size = new Vector2(8f, 0f) },
                        new CanvasWidget {
                            Children = {
                                new RectangleWidget {
                                    Size = new Vector2(128f, 72f),
                                    FillColor = Color.Black * 0.75f,
                                    OutlineColor = Color.Transparent,
                                    IsVisible = value == null
                                },
                                new RectangleWidget {
                                    Size = new Vector2(128f, 72f),
                                    Subtexture = new Subtexture(value, Vector2.Zero, Vector2.One),
                                    FillColor = Color.White,
                                    OutlineColor = Color.Transparent,
                                    IsVisible = value != null
                                }
                            }
                        },
                        new CanvasWidget { Size = new Vector2(20f, 0f) },
                        new StackPanelWidget {
                            Direction = LayoutDirection.Vertical,
                            HorizontalAlignment = WidgetAlignment.Near,
                            VerticalAlignment = WidgetAlignment.Center,
                            Children = {
                                new StackPanelWidget {
                                    HorizontalAlignment = WidgetAlignment.Near,
                                    VerticalAlignment = WidgetAlignment.Center,
                                    Children = {
                                        new LabelWidget { Text = text, FontScale = 0.75f },
                                        new LabelWidget { Text = text2, FontScale = 0.75f, Color = Colors.ForeDim },
                                        new RectangleWidget {
                                            Size = new Vector2(16f, 16f),
                                            Margin = new Vector2(4f, 0f),
                                            Subtexture =
                                                new Subtexture(
                                                    Player.GetPlatformTexture(gameDescription.CreationParameters.CreatingPlayerPlatform),
                                                    Vector2.Zero,
                                                    Vector2.One
                                                ),
                                            FillColor = Colors.ForeDim,
                                            OutlineColor = Color.Transparent,
                                            IsVisible = Player.GetPlatformTexture(gameDescription.CreationParameters.CreatingPlayerPlatform) != null
                                        },
                                        new LabelWidget { Text = text3, FontScale = 0.75f, Color = Colors.ForeDim }
                                    }
                                },
                                new LabelWidget {
                                    Text = text4,
                                    FontScale = 0.75f,
                                    HorizontalAlignment = WidgetAlignment.Near,
                                    VerticalAlignment = WidgetAlignment.Center,
                                    Color = Colors.ForeDim
                                },
                                new LabelWidget {
                                    Text = text5,
                                    FontScale = 0.75f,
                                    HorizontalAlignment = WidgetAlignment.Near,
                                    VerticalAlignment = WidgetAlignment.Center,
                                    Color = Colors.ForeDim
                                }
                            }
                        }
                    }
                };
            };
        }

        public override void Enter(object[] parameters) {
            UpgradeDialogShown = false;
            GamesList.ClearItems();
            if (ScreensManager.m_animationData.OldScreen is not GameSetupScreen) {
                ServersManager.StartServerDiscovery();
            }
        }

        public override void Leave() {
            if (ScreensManager.m_animationData.NewScreen is not GameSetupScreen) {
                ServersManager.StopServerDiscovery();
            }
        }

        public override void Update() {
            if (Input.Back
                || BackButton.IsClicked) {
                ScreensManager.SwitchScreen("RCMainMenu");
                return;
            }
            if (CreateButton.IsClicked) {
                ScreensManager.SwitchScreen("RCGameSetup");
                return;
            }
            if (JoinButton.IsClicked
                && GamesList.SelectedItem != null) {
                NamesManager.EnsureValidPlayerNameExists(
                    delegate { DialogsManager.ShowDialog(this, new ConnectingDialog((GameDescription)GamesList.SelectedItem, false)); }
                );
            }
            if (SpectateButton.IsClicked
                && GamesList.SelectedItem != null) {
                NamesManager.EnsureValidPlayerNameExists(
                    delegate { DialogsManager.ShowDialog(this, new ConnectingDialog((GameDescription)GamesList.SelectedItem, true)); }
                );
            }
            if (Time.PeriodicEvent(0.25, 0.0)) {
                GameDescription gameDescription = (GameDescription)GamesList.SelectedItem;
                IOrderedEnumerable<GameDescription> orderedEnumerable = from s in ServersManager.DiscoveredServers.SelectMany(s => s.GameDescriptions)
                    orderby (s.ServerDescription.IsLocal ? "0" : "1") + s.TicksSinceStart.ToString("D10") + s.GameId.ToString("D10")
                    select s;
                GamesList.ClearItems();
                foreach (GameDescription item in orderedEnumerable) {
                    GamesList.AddItem(item);
                    if (gameDescription != null
                        && Equals(item.ServerDescription.Address, gameDescription.ServerDescription.Address)
                        && item.GameId == gameDescription.GameId) {
                        GamesList.SelectedIndex = GamesList.Items.Count - 1;
                    }
                }
                KeyValuePair<GameDescription, Texture2D>[] array = GameImageTexturesCache.ToArray();
                for (int i = 0; i < array.Length; i++) {
                    KeyValuePair<GameDescription, Texture2D> keyValuePair = array[i];
                    if (!orderedEnumerable.Contains(keyValuePair.Key)) {
                        if (keyValuePair.Value != null) {
                            keyValuePair.Value.Dispose();
                        }
                        GameImageTexturesCache.Remove(keyValuePair.Key);
                    }
                }
            }
            if (!UpgradeDialogShown
                && ServersManager.NewVersionServerDiscovered.HasValue) {
                UpgradeDialogShown = true;
                DialogsManager.ShowDialog(
                    null,
                    new MessageDialog(
                        LanguageControl.Get(fName, "14"),
                        string.Format(
                            LanguageControl.Get(fName, "15"),
                            VersionsManager.Version.ToString(2),
                            ServersManager.NewVersionServerDiscovered.Value.ToString(2)
                        ),
                        LanguageControl.Get(fName, "16"),
                        LanguageControl.Cancel,
                        delegate(MessageDialogButton b) {
                            if (b == MessageDialogButton.Button1) {
                                MarketplaceManager.ShowMarketplace();
                            }
                        }
                    )
                );
            }
            JoinButton.IsVisible = GamesList.SelectedItem != null;
            SpectateButton.IsVisible = GamesList.SelectedItem != null;
            CreateButton.IsVisible = GamesList.SelectedItem == null;
        }

        public static string ShortenAddress(IPAddress address) {
            string text = address.ToString();
            if (text.Length > 15) {
                text = $"{text.Substring(0, 4)}...{text.Substring(text.Length - 8, 8)}";
            }
            return text;
        }
    }
}